﻿package bitmapdata {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.filters.DisplacementMapFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	
	/**
	 * @author Ryan Liu | www.ryan-liu.com
	 * @since 2009-5-3 22:10
	 */
	public class PerlinFire extends Sprite {
		[Embed(source="assets/fire.jpg")]
		private var fire:Class;
		private var sw:int = stage.stageWidth
		private var sh:int = stage.stageHeight
		private var mapLevel:int = 2
		private var fireShape:Shape = new Shape()
		private var fireMap:BitmapData = new BitmapData(sw, sh)
		private var sourceBmd:BitmapData = new BitmapData(sw, sh, true, 0x00ff0000)
		private var fireBmd:BitmapData = new BitmapData(sw, sh)
		private var fireBmp:Bitmap = new Bitmap(fireBmd)
		private var offsetArray:Array = [];
		private var redArray:Array = [];
		private var df:DisplacementMapFilter  = new DisplacementMapFilter(fireMap, new Point(), 1, 2, 5, 10,'clamp')
		private var bf:BlurFilter = new BlurFilter(2, 2, 3)
		
		public function PerlinFire() {
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP;
			//绘制一个渐变色块
			var mtx:Matrix = new Matrix();
			mtx.createGradientBox(400, 50, 90)
			fireShape.graphics.beginGradientFill('linear', [0xff0000, 0xff0000], [0, 1], [0, 255], mtx)
			fireShape.graphics.drawRect(0,0,400,50)
			fireShape.graphics.endFill()
			//给偏移滤镜建立偏移矢量
			for (var i:int = 0; i < mapLevel; i++) {
				offsetArray[i] = new Point()
			}
			addChildAt(fireBmp,0)
			addEventListener(Event.ENTER_FRAME, loop)
			//获得火焰的渐变色
			getNewPalette()
		}
		private function loop(e:Event):void {
			renderFire()
		}
		private function renderFire():void {
			for (var i:int = 0; i < mapLevel; i++) {
				offsetArray[i].y +=(i+1)*4
			}
			fireMap.perlinNoise(25,25,mapLevel,Math.random(),false,true,3,false,offsetArray)
			
			var ctm:ColorTransform = new ColorTransform(.95, .95, .95)
			var mtx:Matrix = new Matrix()
			mtx.tx = 0
			mtx.ty = 250
			
			sourceBmd.scroll(0,-5)
			sourceBmd.colorTransform(sourceBmd.rect, ctm)
			sourceBmd.draw(fireShape, mtx, new ColorTransform(1, 0, 0))
			sourceBmd.applyFilter(sourceBmd,sourceBmd.rect,new Point(),bf)
			sourceBmd.applyFilter(sourceBmd, sourceBmd.rect, new Point(), df)
			fireBmd.paletteMap(sourceBmd, fireBmd.rect, new Point(), redArray)

		}
		private function getNewPalette():void {
			var sampleBmd:BitmapData = new BitmapData(256, 1)
//			sampleBmd.draw(new fire() as Bitmap)
				
			var colorSample:Sprite = new Sprite();
			colorSample.graphics.beginGradientFill("linear",[0,0xFF0000,0xfff000],[1,1,1],[0,128,255]);
			colorSample.graphics.drawRect(0,0,100,2);
			colorSample.graphics.endFill();
			sampleBmd.draw(colorSample);
			this.addChild(colorSample);
			for (var i:int = 0; i < 100; i++) {
				redArray.push(sampleBmd.getPixel(i, 0))
			}
//			colorSample.visible = false
		}
		
	}
}